// 2025/10/31
// 单词搜索二

struct TrieNode {
    string word;
    unordered_map<char,TrieNode *> children;
    TrieNode() {
        this->word = "";
    }   
};

void insertTrie(TrieNode * root,const string & word) {
    TrieNode * node = root;
    for (auto c : word){
        if (!node->children.count(c)) {
            node->children[c] = new TrieNode();
        }
        node = node->children[c];
    }
    node->word = word;
}

class Solution {
public:
    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    bool dfs(vector<vector<char>>& board, int i, int j, TrieNode* root, set<string> &res)
    {
        char ch = board[i][j];
        if(!root->children.count(ch))
            return false;
        root = root->children[ch];
        if(root->word.size() > 0)
            res.insert(root->word);

        board[i][j] = 0;
        for(auto &dir : dirs)
        {
            int x = i + dir[0], y = j + dir[1];
            if(0 <= x && x < board.size() && 0 <= y && y < board[0].size() && board[x][y] != 0)
                dfs(board, x, y, root, res);
        }
        board[i][j] = ch;
        return true;
    }

    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        TrieNode *root = new TrieNode();
        set<string> res;

        for(auto &word : words)
            insertTrie(root, word);
        for(int i = 0; i < board.size(); i++)
        {
            for(int j = 0; j < board[0].size(); j++)
            {
                dfs(board, i, j, root, res);
            }
        }
        vector<string> ans(res.begin(), res.end());
        return ans;
    }
};